#include "pch.h"
#include "token.h"

bool token_stream::eof()
{
	if (!file) return true;
	wchar_t ch;
	file.get(ch);
	if (file.eof())
	{
		return true;
	}
	file.putback(ch);
	return false;
}

void token_stream::putback(Token t)
{
	buffer.push(t);
}

Token token_stream::get_token()

{
	if (!buffer.empty())
	{
		Token t = buffer.top();
		buffer.pop();
		return t;
	}
	if (eof()) return none_token;
	wchar_t ch;
	file.get(ch);
	if (isdigit(ch))
	{
		file.putback(ch);
		double v;
		file >> v;
		return Token(v);
	}
	if (ch == LSTR_TOKEN || ch == LDSTR_TOKEN)
	{
		ch = ch == LSTR_TOKEN ? RSTR_TOKEN : RDSTR_TOKEN;
		wchar_t c;
		file.get(c);
		std::wstring str = L"";
		while (c != ch)
		{
			if (eof()) return Token(str);
			str += c;
			file.get(c);
		}
		return Token(str);
	}
	switch (ch)
	{
	case L' ':
	case L'\t':
	case L'\n':
		while (ch == L' ' || ch == L'\t' || ch == L'\n')
			ch = file.get();
		file.putback(ch);
		return get_token();
		break;
	case END_TOKEN:
	case NEXT_TOKEN:
	case LTYPE_TOKEN:
	case RTYPE_TOKEN:
	case LMETHOD_TOKEN:
	case RMETHOD_TOKEN:
	case DESCRIBE_TOKEN:
	case TAG_TOKEN:
	case DEFINE_TOKEN:
	case LAREA_TOKEN:
	case RAREA_TOKEN:
		return Token(SYMBAL_TOKEN, ch);
		break;
	case AND_TOKEN:
	case DOT_TOKEN:
	case ASG_TOKEN:
	case HAVE_TOKEN:
	case TALK_TOKEN:
		return Token(KEYWORD_TOKEN, ch);
		break;
	}
	return Token(ch);
}
